import {ElMessage} from "element-plus";
import {onMounted, shallowRef, unref} from "vue";
import dayjs from "dayjs";
import {breadcrumbsHeight, headerHeight, mainMargin, topTitleHeight} from '@/assets/styles/vars.module.scss'


// 服务模块前缀路径
export const serviceModulePrefix = '/bksystem'


/**
 * @description 在@/utils/request.js封装的axios的基础上进一步封装
 * @param {Promise} apiPromise
 * @param {*} opts 可自定义一些状态参数
 */
export const useDecorateApi = (apiPromise, opts = {}) => {
  const {
    toast = true,
    dataRef = ref({}),
    loadingRef = ref(false),
    isSuccess = ({code}) => code === 200,
    dataCleaning = res => res
  } = opts

  loadingRef.value = true
  const promise = new Promise((resolve, reject) => {
    apiPromise.finally(() => {
      loadingRef.value = false
    }).then((res = {}) => {
      if (!isSuccess(res)) {
        if (toast) ElMessage.warning(res.msg || '请稍后再试')
        reject(res)
      } else {
        dataRef.value = dataCleaning(res)
        resolve(res)
      }
    }).catch(() => {
      ElMessage.warning('请稍后再试')
    })
  })

  return {
    promise,
    dataRef,
    loadingRef
  }
}


/**
 * @description 分页功能的列表查询
 * @param {Function} api
 * @param {*} opts
 */
export const usePagerList = (api, opts = {}) => {
  const {
    immediate = true,
    pageSize = 10,
    pageNum = 1,
    queryRef = ref({}),// 额外的筛选参数
    listRef = ref([]),// 默认列表数据
    totalRef = ref(0),
    loadingRef = ref(false)
  } = opts

  const pagerRef = ref({
    pageNum,
    pageSize
  })

  const getList = () => {
    if (!api) return
    loadingRef.value = true
    const {promise} = api({...unref(pagerRef), ...unref(queryRef)}, {loadingRef})
    listRef.value = []
    promise.then(({rows = [], total = 0}) => {
      listRef.value = rows
      totalRef.value = total
    })
  }

  const handlePager = (e) => {
    pagerRef.value.pageNum = e
    getList()
  }

  const reFetch = () => {
    if (unref(loadingRef)) return ElMessage.warning('请勿频繁操作')
    pagerRef.value.pageNum = pageNum
    getList()
  }

  if (immediate) reFetch()

  return {
    pagerRef,
    queryRef,
    listRef,
    totalRef,
    loadingRef,
    handlePager,
    reFetch
  }
}


/**
 * @description 计算最大可容纳列数
 * @param {number} itemWidth 每项的宽度px
 * @param {number} itemGap 最小间距px
 */
export const useGirdColsFix = (itemWidth = 100, itemGap = 10) => {
  const domRef = shallowRef(null)
  const columns = ref(1)

  onMounted(() => {
    let dom = unref(domRef)
    if (Array.isArray(dom)) dom = dom[0]
    if (!dom) return
    const style = window.getComputedStyle(dom);
    // 默认认为border-box
    const boxWidth = parseInt(style.width) - parseInt(style.paddingLeft) - parseInt(style.paddingRight);
    // 列数应满足不等式 columns * itemWidth + (columns - 1) * itemGap < boxWidth 变形可得
    columns.value = parseInt((boxWidth + itemGap) / (itemWidth + itemGap))
  })

  return {
    itemWidth,
    domRef,
    columns
  }
}


export const checkPhone = val => /^1[3-9]\d{9}$/.test(val)

export const formatDate = (time, template = 'YYYY-MM-DD') => time ? dayjs(+time).format(template) : ''


export const bigint2StrInJson = (jsonStr) => JSON.parse(jsonStr.replace(/:\s*([-+Ee0-9.]+)/g, ': "$1"'))


export const useFileSelector = (opts = {}) => {
  const {accept = '.xls, .xlsx', success} = opts
  const fileRef = shallowRef(null)
  const inputEle = document.createElement('input')
  inputEle.type = 'file'
  inputEle.accept = accept

  const changeListener = e => {
    const files = e.target.files
    inputEle.removeEventListener('change', changeListener)
    if (files.length === 1) {
      fileRef.value = files[0]
      success && success(fileRef.value)
    }
  }
  inputEle.addEventListener('change', changeListener)
  inputEle.click()

  return {
    fileRef
  }
}

/** 这是一个临时解决方式，用于修正主视图滚动条高度(有面包屑时主视图上边距更高，滚动条高度应修正)
 */
export const useViewScrollbarHeight = (breadcrumbs = false) => {
  // App.vue里provide了fixMainScrollbarHeight，并在多个组件中参与高度计算
  const fixMainScrollbarHeight = inject('App:fixMainScrollbarHeight', ref(breadcrumbs ? breadcrumbsHeight : mainMargin))

  if (breadcrumbs) {
    fixMainScrollbarHeight.value = breadcrumbsHeight
    onUnmounted(() => {
      fixMainScrollbarHeight.value = mainMargin
    })
  }

  // 主视图滚动条高度计算属性
  const mainScrollbarHeightStyle = computed(() => `calc(100vh - ${headerHeight} - ${mainMargin} - ${unref(fixMainScrollbarHeight)})`)

  // 主视图内层视图计算属性(主视图减去标题栏高度)
  const innerScrollbarHeightStyle = computed(() => `calc(${unref(mainScrollbarHeightStyle)} - ${topTitleHeight})`)

  return {
    mainScrollbarHeightStyle,
    innerScrollbarHeightStyle,
    fixMainScrollbarHeight
  }
}

/** 根据buffer在本地下载
 */
export const createBlobDownload = (fileName = 'unknown', blob) => {
  const a = document.createElement("a");
  a.download = fileName
  a.target = "_blank";
  a.href = URL.createObjectURL(blob);
  a.click();
  a.remove()
}


//读取本地json
export const readLocalJSON = (file)=>{
  return new Promise((resolve,reject)=>{
    const reader = new FileReader();
    reader.onload = (event) => {        
        resolve(event.target.result)              
    };
    reader.readAsText(file); 
  })
}
